﻿#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>
#include <QDebug>
#include <QString>
#include <QSound>
#include <QStringLiteral>
#include "warnthread.h"

bool warnplay = false;


Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    ui->label_refer->setStyleSheet(QString::fromUtf8("border:1px solid black"));
    ui->label_video->setStyleSheet(QString::fromUtf8("border:1px solid black"));

    videocapture = new VideoCapture(0);
    if(0 == videocapture)
    {
        QMessageBox::warning(NULL, QStringLiteral("警告"), "open videocapture error");
        qApp->exit(-1);
    }
    else {

        ok = true;

        sensitivity = 20;
        ui->horizontalSlider->setValue(100-sensitivity);


        setrefer = false;
        monitor = false;
        warnplay = false;
        move = false;

        videocapture->set(CV_CAP_PROP_FPS, 25);//帧率 帧/秒
        videocapture->set(CAP_PROP_FRAME_WIDTH, 640);
        videocapture->set(CAP_PROP_FRAME_HEIGHT, 360);

        timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(readFarme()));  // 时间到，读取当前摄像头信息
        timer->start(40);
    }
}

Widget::~Widget()
{
    delete ui;
}

QImage Widget::cvMat2QImage(const Mat& mat)    // Mat 改成 QImage
{
    if (mat.type() == CV_8UC1)                  // 单通道
    {
        QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
        image.setColorCount(256);               // 灰度级数256
        for (int i = 0; i < 256; i++)
        {
            image.setColor(i, qRgb(i, i, i));
        }
        uchar *pSrc = mat.data;                 // 复制mat数据
        for (int row = 0; row < mat.rows; row++)
        {
            uchar *pDest = image.scanLine(row);
            memcpy(pDest, pSrc, mat.cols);
            pSrc += mat.step;
        }
        return image;
    }

    else if (mat.type() == CV_8UC3)             // 3通道
    {
        const uchar *pSrc = (const uchar*)mat.data;         // 复制像素
        QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);    // R, G, B 对应 0,1,2
        return image.rgbSwapped();              // rgbSwapped是为了显示效果色彩好一些。
    }
    else if (mat.type() == CV_8UC4)
    {
        const uchar *pSrc = (const uchar*)mat.data;         // 复制像素
                                                            // Create QImage with same dimensions as input Mat
        QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);        // B,G,R,A 对应 0,1,2,3
        return image.copy();
    }
    else
    {
        return QImage();
    }
}

Mat Widget::QImage2cvMat(QImage image)           // QImage改成Mat
{
    Mat mat;
    switch (image.format())
    {
    case QImage::Format_ARGB32:
    case QImage::Format_RGB32:
    case QImage::Format_ARGB32_Premultiplied:
        mat = Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());
        break;
    case QImage::Format_RGB888:
        mat = Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());
        cv::cvtColor(mat, mat, CV_BGR2RGB);
        break;
    case QImage::Format_Indexed8:
        mat = Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
        break;
    }
    return mat;
}

void Widget::readFarme()
{
    videocapture->read(matFrame);
    QImage imgg = cvMat2QImage(matFrame);
    QPixmap qpixmap = QPixmap::fromImage(imgg);
    // 将图片显示到label上
    this->ui->label_video->setPixmap(qpixmap);


    if(!monitor)
        return;
    if(!move)
    {
        int sub = 0;
        int sen = sensitivity * 200000;
        for(int i = 0; i < 640; i++)
            for(int j = 0; j < 360; j++)
            {
                QRgb pixel=imgg.pixel(i,j);
                unsigned char grey = qGray(qRed(pixel),qGreen(pixel),qBlue(pixel));
                if (grey > greyrefer[i][j])
                    sub += grey - greyrefer[i][j];
                else
                    sub += greyrefer[i][j]-grey;
            }
        if (sub > sen)
            move = true;
    }
    if(move)
    {
        warnplay = true;
        playwav();
    }
}


void Widget::playwav()
{
    QSound *sound = new QSound(":/new/prefix1/warn2.wav", this); //构建对
    sound->play();//播放
}

//获取参照图片
void Widget::getrefer()
{
    videocapture->read(matFrame);
    refer_image = cvMat2QImage(matFrame);
    QPixmap qpixmap = QPixmap::fromImage(refer_image);
    // 将图片显示到label上
    this->ui->label_refer->setPixmap(qpixmap);
    for(int i = 0; i < 640; i++)
        for(int j = 0; j < 360; j++)
        {
            QRgb pixel=refer_image.pixel(i,j);
            greyrefer[i][j] = qGray(qRed(pixel),qGreen(pixel),qBlue(pixel));
        }
}

//获取参照图片
void Widget::on_pushButton_clicked()
{
    this->getrefer();
    setrefer = true;
}

//开始、暂停监测
void Widget::on_pushButton_2_clicked()
{
    if (!monitor)
    {
        if(!setrefer)
        {
            this->getrefer();
            setrefer = true;
        }
        monitor = true;
        this->ui->pushButton_2->setText(QStringLiteral("停止监测"));
    }
    else
    {
        monitor = false;
        move = false;
        setrefer = false;
        this->ui->pushButton_2->setText(QStringLiteral("开始监测"));
    }
}


void Widget::on_horizontalSlider_valueChanged(int value)
{
    qDebug("slider %d %d", value);
    sensitivity = 100-value;
}

//关闭、打开告警
void Widget::on_pushButton_3_clicked()
{

}

//关闭、打开告警
void Widget::on_pushButton_4_clicked()
{

}
